<!--
作者：dailc
时间：2016-11-12
描述：js实现的瀑布流效果
需求来源:在搭建个人博客的demo展示页时
所有示例都只确保在chrome中和移动端正常运行
-->
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <!-- 让国内基于webkit的浏览器默认采用webkit内核进行渲染 -->
    <meta name="renderer" content="webkit" />
    <!-- 移动端的响应式特性 -->
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta content="js,javascript,瀑布流,js效果,js实践" name="Keywords">
    <meta content="js实现瀑布流效果" name="description">
    <title>js瀑布流效果</title>
    <!-- <link rel="stylesheet" href="../common/css/reset.css" /> -->
    <style>
    /*样式只是用来美化效果而已*/

    .demo-container {
        position: relative;
        min-height: 1px;
        padding-right: 15px;
        padding-left: 15px
    }

    a,
    a:focus,
    a:hover {
        text-decoration: none;
        transition: 0.5s ease;
    }
    /*
* demo grid布局
*/

    .grid .grid-item {
        /*
* 因为高度是与宽度相关的，所以手动设置item宽度，避免计算误差
* 这点在某些布局里比较重要
*/
        width: 240px;
        margin-bottom: 20px;
        padding-bottom: 10px;
        border: 1px solid rgba(0, 0, 0, 0.3);
        background-color: #fff;
        transition: 0.5s ease;
        -webkit-transition: 0.5s ease;
        -moz-transition: 0.5s ease;
        -webkit-box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
        -moz-box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
    }

    .grid .grid-item img {
        width: 100%;
    }

    .grid .grid-item:hover {
        transition: 0.5s ease;
        -webkit-transition: 0.5s ease;
        -moz-transition: 0.5s ease;
        -webkit-box-shadow: 0px 2px 30px 0px rgba(0, 0, 0, 0.67);
        -moz-box-shadow: 0px 2px 30px 0px rgba(0, 0, 0, 0.67);
        box-shadow: 0px 2px 30px 0px rgba(0, 0, 0, 0.67);
    }
    /*
* item里的内容样式
*/

    .grid .grid-item h3,
    .grid .grid-item p {
        margin: 0;
        padding: 0 8px;
    }

    .grid .grid-item h3 {
        margin: 10px 0;
        font-size: 18px;
    }

    .grid .grid-item p {
        margin-top: 5px;
        font-size: 14px;
    }

    .grid .grid-item .icon-code:before {
        content: '</>';
    }
    </style>
</head>

<body>
    <!--请保持dom结构,grid-container,grid,grid-item 命名可以更换 -->
    <div class="grid-container">
        <div class="grid">
            <!--<div class="grid-item">
<a class="demo-img" href="https://github.com/dailc">
<img src="https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_1.jpg">
</a>
<h3 class="demo-title">
<a href="https://github.com/dailc">Hybrid示例应用</a>
</h3>
<p>技术分类：js Hybrid模式</p>
<p>混合开发，原生容器，h5+js进行业务功能开发，提升开发效率
<a href="https://github.com/dailc">源代码 <i class="icon icon-code" ></i></a>
</p>
</div>-->
        </div>
    </div>
    <script type="text/javascript" src="/toupiao/js/waterfallFlow.js"></script>
    <script>
    //拓展瀑布流类库的用法示例
    var myWaterFlow = WaterfallFlow.flow.extend({
        /**
         * @description 实现这个方法,可以在这个方法里面增加自己想要做的事情
         * 这个方法默认初始化就会调用
         */
        doExtendJob: function() {
            console.log("doMyjob");
            this.listenScroll();
        },
        /**
         * @description 自己拓展的加载更多
         */
        loadMore: function() {
            var self = this;
            console.log("加载更多");
            //这里模拟添加效果,500ms后调用load api添加一个元素
            setTimeout(function() {
                self.load('<div class="grid-item"><a class="demo-img"href="https://github.com/dailc"><img src="https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_1.jpg"></a><h3 class="demo-title"><a href="https://github.com/dailc">Hybrid示例应用</a></h3><p>技术分类：js Hybrid模式</p><p>混合开发，原生容器，h5+js进行业务功能开发，提升开发效率<a href="https://github.com/dailc">源代码<i class="icon icon-code"></i></a></p></div>');
                self.load('<div class="grid-item"><a class="demo-img"href="https://github.com/dailc"><img src="https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_1.jpg"></a><h3 class="demo-title"><a href="https://github.com/dailc">Hybrid示例应用</a></h3><p>技术分类：js Hybrid模式</p><p>混合开发，原生容器，h5+js进行业务功能开发，提升开发效率<a href="https://github.com/dailc">源代码<i class="icon icon-code"></i></a></p></div>');
            }, 500);
        },
        /**
         * @description 监听滑动
         */
        listenScroll: function() {
            var self = this;
            //增加滑动监听
            window.addEventListener('scroll', function() {
                var scrollTop = getScrollTop();
                var winHeight = getWindowHeight();
                var scrollHeight = getScrollHeight();
                if (scrollTop + winHeight >= scrollHeight) {
                    self.loadMore();
                }
            });
        }
    });
    /**
     * @description 获取滚动条在Y轴上的滚动距离
     * @return {Number} 返回具体距离
     */
    function getScrollTop() {
        var scrollTop = 0,
            bodyScrollTop = 0,
            documentScrollTop = 0;
        if (document.body) {
            bodyScrollTop = document.body.scrollTop || 0;
        }
        if (document.documentElement) {
            documentScrollTop = document.documentElement.scrollTop || 0;
        }
        scrollTop = (bodyScrollTop > documentScrollTop) ? bodyScrollTop : documentScrollTop;
        return scrollTop;
    }
    /**
     * @description 获取文档的总高度
     * @return {Number} 返回具体高度
     */
    function getScrollHeight() {
        var scrollHeight = 0,
            bodyScrollHeight = 0,
            documentScrollHeight = 0;
        if (document.body) {
            bodyScrollHeight = document.body.scrollHeight;
        }
        if (document.documentElement) {
            documentScrollHeight = document.documentElement.scrollHeight;
        }
        scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
        return scrollHeight;
    };
    /**
     * @description 浏览器视口的高度
     * @return {Number} 返回具体高度
     */
    function getWindowHeight() {
        var windowHeight = 0;
        if (document.compatMode == "CSS1Compat") {
            windowHeight = document.documentElement.clientHeight;
        } else {
            windowHeight = document.body.clientHeight;
        }
        return windowHeight;
    };
    //使用瀑布流的代码
    var demo = {
        /**
         * @description 初始化网格布局
         */
        initGrid: function() {
            //记录添加的数据
            var index = 0;
            //如果需要适配手机端，可以修改宽度
            var flow = new myWaterFlow('.grid-container', {
                gridSelector: '.grid',
                itemSelector: '.grid-item',
                columnWidth: 240,
                gutter: 20,
                loadSuccess: function(self, isInit) {
                    //console.log("success");
                    if (isInit) {
                        //self.load('<div class="grid-item"><a class="demo-img"href="{{demoLink}}"><img src="{{imgLink}}"></a><h3 class="demo-title"><a href="{{demoLink}}">{{title}}</a></h3><p>技术分类：{{relevant}}</p><p>{{description}}<a href="{{codeLink}}">&nbsp;&nbsp;源代码&nbsp;&nbsp;<i class="icon icon-code"></i></a></p></div>'); //可以单独添加item
                    } else {
                        //比如加载更多时单独添加进入的元素添加完毕
                    }
                }
            });
            return flow;
        },
        /**
         * @description 通过content生成html
         * @param {Array} content
         */
        getHtmlByContent: function(content) {
            var html = '';
            var litemplate =
                '<div class="grid-item"><a class="demo-img"href="{{demoLink}}"><img src="{{imgLink}}"></a><h3 class="demo-title"><a href="{{demoLink}}">{{title}}</a></h3><p>技术分类：{{relevant}}</p><p>{{description}}<a href="{{codeLink}}">&nbsp;&nbsp;源代码&nbsp;&nbsp;<i class="icon icon-code"></i></a></p></div>';
            for (var i = 0, len = content.length; i < len; i++) {
                var tmp = content[i];
                html += litemplate.replace(/\{\{demoLink\}\}/g, tmp.demoLink)
                    .replace(/\{\{imgLink\}\}/g, tmp.imgLink)
                    .replace(/\{\{codeLink\}\}/g, tmp.codeLink)
                    .replace(/\{\{relevant\}\}/g, tmp.relevant)
                    .replace(/\{\{title\}\}/g, tmp.title)
                    .replace(/\{\{description\}\}/g, tmp.description);
            }
            return html;
        },
        /**
         * @description demo页面初始化
         */
        init: function() {
            var demoContent = [{
                demoLink: 'http://www.cnblogs.com/dailc/p/5930231.html',
                imgLink: 'https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_1.jpg',
                codeLink: 'https://github.com/dailc',
                title: 'Hybrid示例应用',
                relevant: 'js Hybrid模式',
                description: '混合开发，原生容器，h5+js进行业务功能开发，提升开发效率'
            }, {
                demoLink: 'https://github.com/dailc',
                imgLink: 'https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_2.jpg',
                codeLink: 'https://github.com/dailc',
                title: 'Hybrid示例应用',
                relevant: 'js Hybrid模式',
                description: '混合开发，原生容器，h5+js进行业务功能开发，提升开发效率'
            }, {
                demoLink: 'http://www.cnblogs.com/dailc/p/5930231.html',
                imgLink: 'https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_3.jpg',
                codeLink: 'https://github.com/dailc',
                title: 'Hybrid示例应用',
                relevant: 'js Hybrid模式',
                description: '混合开发，原生容器，h5+js进行业务功能开发，提升开发效率'
            }, {
                demoLink: 'https://github.com/dailc',
                imgLink: 'https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_3.jpg',
                codeLink: 'https://github.com/dailc',
                title: 'Hybrid示例应用',
                relevant: 'js Hybrid模式',
                description: '混合开发，原生容器，h5+js进行业务功能开发，提升开发效率'
            }, {
                demoLink: 'http://www.cnblogs.com/dailc/p/5930231.html',
                imgLink: 'https://dailc.github.io/staticResource/blog/hybrid/img_hybrid_base_hybridInfo_2.jpg',
                codeLink: 'https://github.com/dailc',
                title: 'Hybrid示例应用',
                relevant: 'js Hybrid模式',
                description: '混合开发，原生容器，h5+js进行业务功能开发，提升开发效率'
            }];
            var html = this.getHtmlByContent(demoContent);
            var grid = document.querySelector('.grid');
            //注意，初始化添加的item 请控制它的高度
            //有一种情况是item的高是与宽适应的，而初始化宽为100%，导致高度很高
            //所以在计算时，初始化的高度会变得不正确，这时候就需要自己去css中手动将宽度设置为传入的一致，避免误差
            grid.innerHTML = html;
            //初始化
            var flow = this.initGrid();
            //如果单独的load可以参考 initGrid里的代码 flow.load()即可添加,注意selector请和class保持一致
        }
    };
    //初始化
    demo.init();
    </script>
</body>

</html>